package com.atguigui.gulimall.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.utils.R;
import com.atguigui.gulimall.cart.constant.CartConstant;
import com.atguigui.gulimall.cart.feign.ProductFeign;
import com.atguigui.gulimall.cart.interceptor.CartInterceptor;
import com.atguigui.gulimall.cart.service.CartService;
import com.atguigui.gulimall.cart.vo.CartItemVo;
import com.atguigui.gulimall.cart.vo.CartVo;
import com.atguigui.gulimall.cart.vo.SkuInfoEntity;
import com.atguigui.gulimall.cart.vo.UserInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {
    @Autowired
    private ProductFeign productFeign;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public CartItemVo addCartItem(Long skuId, Integer num) throws ExecutionException, InterruptedException {
        BoundHashOperations<String, Object, Object> cart = getCart();
        String product = (String) cart.get(skuId.toString());
        if(product==null){
            CartItemVo cartItemVo = new CartItemVo();
            CompletableFuture<Void> skuInfoCompletableFuture = CompletableFuture.runAsync(() -> {
                //远程查询skuinfo
                R r = productFeign.info(skuId);
                SkuInfoEntity skuInfoEntity = r.getData("skuInfo", new TypeReference<SkuInfoEntity>() {
                });
                cartItemVo.setPrice(skuInfoEntity.getPrice());
                cartItemVo.setAmount(num);
                cartItemVo.setSkuImg(skuInfoEntity.getSkuDefaultImg());
                cartItemVo.setTotalPrice(cartItemVo.getTotalPrice());
                cartItemVo.setSkuId(skuId);

                cartItemVo.setTitle(skuInfoEntity.getSkuTitle());
            }, threadPoolExecutor);

            CompletableFuture<Void> attrCompletableFuture = CompletableFuture.runAsync(() -> {
                //远程查询sku属性信息
                List<String> skuSaleAttrs = productFeign.skuSaleAttrs(skuId);
                cartItemVo.setAttrs(skuSaleAttrs);
            }, threadPoolExecutor);
            CompletableFuture.allOf(skuInfoCompletableFuture,attrCompletableFuture).get();

            String toJSONString = JSON.toJSONString(cartItemVo);
            getCart().put(skuId.toString(),toJSONString);
            return cartItemVo;
        }else {
            //修改数量
            CartItemVo cartItemVo = JSON.parseObject(product, CartItemVo.class);
            cartItemVo.setAmount(cartItemVo.getAmount()+num);
            String toJSONString = JSON.toJSONString(cartItemVo);
            cart.put(skuId.toString(),toJSONString);
            return cartItemVo;
        }


    }

    @Override
    public CartVo cart() throws ExecutionException, InterruptedException {
        CartVo cartVo = new CartVo();
        BoundHashOperations<String, Object, Object> cart = getCart();
        UserInfo userInfo = CartInterceptor.threadLocal.get();

        String userKey = "";
        userKey = CartConstant.CART_PREFIX+userInfo.getUserKey();
        List<CartItemVo> cartItemVos = getCartItem(userKey);

        if(!StringUtils.isEmpty(userInfo.getUserId())){

            String userKey1 = CartConstant.CART_PREFIX+userInfo.getUserId();
            List<CartItemVo> cartItems = getCartItem(userKey1);

            if(cartItemVos!=null){
                for (CartItemVo cartItemVo : cartItemVos) {
                    addCartItem(cartItemVo.getSkuId(),cartItemVo.getAmount());
                }
                stringRedisTemplate.delete(userKey);
            }
            cartVo.setItems(getCartItem(userKey1));
            return cartVo;
        }else {
            cartVo.setItems(cartItemVos);
            //没有登录
            return cartVo;
        }

    }

    @Override
    public CartItemVo getCartItemVoBySkuId(String skuId) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        String str = (String) cart.get(skuId);
        CartItemVo cartItemVo = JSON.parseObject(str, CartItemVo.class);
        return cartItemVo;
    }

    @Override
    public void checkItem(String skuId, Integer checked) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        String str = (String) cart.get(skuId);
        CartItemVo cartItemVo = JSON.parseObject(str, CartItemVo.class);
        cartItemVo.setCheck(checked==1?true:false);
        String s = JSON.toJSONString(cartItemVo);
        cart.put(skuId,s);
    }

    @Override
    public void countItem(String skuId, Integer num) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        String str = (String) cart.get(skuId);
        CartItemVo cartItemVo = JSON.parseObject(str, CartItemVo.class);
        cartItemVo.setAmount(num);
        String s = JSON.toJSONString(cartItemVo);
        cart.put(skuId,s);
    }

    @Override
    public void deleteItem(String skuId) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        cart.delete(skuId);
    }

    @Override
    public List<CartItemVo> getCheckedCart() {
        BoundHashOperations<String, Object, Object> cart = getCart();

        List<Object> values = cart.values();
        if(values!=null && values.size()>0){
            List<CartItemVo> collect = values.stream().map(obj -> {
                String str = (String) obj;
                CartItemVo cartItemVo = JSON.parseObject(str, CartItemVo.class);
                R r = productFeign.info(cartItemVo.getSkuId());
                if(r.getCode()==0){
                    SkuInfoEntity data = r.getData("skuInfo", new TypeReference<SkuInfoEntity>() {});
                    cartItemVo.setPrice(data.getPrice());
                }
                return cartItemVo;
            }).filter(cartItemVo -> {
                return cartItemVo.isCheck();
            }).collect(Collectors.toList());
            return collect;
        }
        return null;

    }

    //根据用户查所有的购物项
    private List<CartItemVo> getCartItem(String userKey) {
        BoundHashOperations<String, Object, Object> hashOperations = stringRedisTemplate.boundHashOps(userKey);
        List<Object> values = hashOperations.values();
        if(values!=null){
            List<CartItemVo> cartItemVos = values.stream().map(obj -> {
                String str = (String) obj;
                CartItemVo cartItemVo = JSON.parseObject(str, CartItemVo.class);
                return cartItemVo;
            }).collect(Collectors.toList());
            return cartItemVos;
        }
        return null;
    }

    //获取当前用户购物车
    public BoundHashOperations<String, Object, Object>  getCart() {
        UserInfo userInfo = CartInterceptor.threadLocal.get();
        String userKey = "";
        if(userInfo.getUserId()!=null){
            userKey = CartConstant.CART_PREFIX+userInfo.getUserId();
        }else {
            userKey = CartConstant.CART_PREFIX+userInfo.getUserKey();
        }
        BoundHashOperations<String, Object, Object> boundHashOperations = stringRedisTemplate.boundHashOps(userKey);
        return boundHashOperations;
    }
}
